﻿#include "scriptmanager.h"
#include "ui_scriptmanager.h"
#include <QSettings>
#include <QMessageBox>
#include <QFileDialog>
#include <QInputDialog>
#include <QDirIterator>
#include <QFile>
#include <QDir>
#include <QDebug>
#include <QTemporaryDir>

ScriptManager::ScriptManager(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ScriptManager)
{
    ui->setupUi(this);
    this->setWindowTitle(QStringLiteral("脚本行家"));
    QSettings *reg = new QSettings("HKEY_CURRENT_USER\\Software\\ScriptWizard", QSettings::NativeFormat);
    m_scriptDir = reg->value("ScriptPath").toString();
    if(!m_scriptDir.trimmed().isEmpty()){
        ui->lineEdit->setText(m_scriptDir);
    }
    m_lastClass = "";
    m_lastScript = "";
    ScanClasses();
}

ScriptManager::~ScriptManager()
{
    delete ui;
}

void ScriptManager::closeEvent(QCloseEvent *event)
{
    if(ui->listnames->currentItem()){
        CheckSave(ui->listnames->currentItem()->text());
    } else {
        //event->ignore();
    }
    event->accept();
}

void ScriptManager::ScanClasses()
{
    QDirIterator iter(m_scriptDir, QDirIterator::Subdirectories);
    while (iter.hasNext()) {
        iter.next();
        QFileInfo info = iter.fileInfo();
        if (info.isDir()) {
            if(info.baseName().isEmpty()){
                continue;
            }
            ui->listclasses->addItem(info.baseName());
            m_classList << info.baseName();
        }
    }
    if(ui->listclasses->count()){
        ui->listclasses->setCurrentRow(0);
        m_lastClass = ui->listclasses->currentItem()->text();
        ScanScripts(m_lastClass);
    }
}

void ScriptManager::ScanScripts(QString classname)
{
    if(classname.trimmed().isEmpty()){
        return;
    }
    m_lastClass = ui->listclasses->currentItem()->text();
    m_tag = false;
    ui->listnames->clear();
    ui->plainTextEdit->setPlainText("");
    m_scriptList.clear();
    QDirIterator iter(m_scriptDir+"/"+classname, QDirIterator::Subdirectories);
    while (iter.hasNext()) {
        iter.next();
        QFileInfo info = iter.fileInfo();
        if (info.isFile()) {
            if(info.baseName().isEmpty()){
                continue;
            }
            m_scriptList << info.fileName();
            ui->listnames->addItem(m_scriptList.last());
        }
    }
}

bool ScriptManager::CheckSave(QString scriptname)
{
    if(scriptname.trimmed().isEmpty()){
        return false;
    }
    if(scriptname.trimmed().endsWith("*")){
        QString dlgTitle = QStringLiteral("脚本保存");
        QString strInfo = QStringLiteral("文件已被修改，是否保存修改？");
        QMessageBox::StandardButton  defaultBtn=QMessageBox::NoButton; //缺省按钮
        QMessageBox::StandardButton result;//返回选择的按钮
        result=QMessageBox::question(this, dlgTitle, strInfo,
                                     QMessageBox::Yes|QMessageBox::No |QMessageBox::Cancel,
                                     defaultBtn);
        if (result==QMessageBox::Yes){
            QFile file(m_scriptDir+"/"+m_lastClass+"/"+scriptname.trimmed().remove("*"));
            if(file.open(QIODevice::WriteOnly|QIODevice::Truncate)){
                file.write(ui->plainTextEdit->toPlainText().replace("\n","\r\n").toLocal8Bit());
            }
            file.close();
            return true;
        }
        else if(result==QMessageBox::No){
            return true;
        }
        else if(result==QMessageBox::Cancel){
            return false;
        }
    }
    return false;
}

void ScriptManager::LoadScript(QString scriptname)
{
    m_tag = false;
    QFile file(m_scriptDir+"/"+m_lastClass+"/"+scriptname);
    if(file.open(QIODevice::ReadOnly)){
        ui->plainTextEdit->setPlainText(QString::fromLocal8Bit(file.readAll()));
        file.close();
    }else{
        ui->plainTextEdit->setPlainText("");
    }
    m_tag = true;
}

void ScriptManager::on_btnAddClass_clicked()
{
    if(m_scriptDir.trimmed().isEmpty()){
        QMessageBox::information(NULL,QStringLiteral("增加分类"),QStringLiteral("请先设置脚本目录"));
        return;
    }
    QString classname = QInputDialog::getText(this,QStringLiteral("增加分类"),QStringLiteral("请输入类别名称"));
    if(classname.trimmed().isEmpty()){
        return;
    }
    if(m_classList.contains(classname)){
        QMessageBox::information(NULL,QStringLiteral("增加分类"),QStringLiteral("该分类已存在"));
        ui->listclasses->setCurrentRow(m_classList.indexOf(classname));
        return;
    }
    m_classList << classname;
    ui->listclasses->addItem(classname);
    QDir dir;
    dir.mkpath(m_scriptDir+"/"+classname);
}

void ScriptManager::on_btnAddScript_clicked()
{
    if(!ui->listclasses->currentItem()){
        QMessageBox::information(NULL,QStringLiteral("增加脚本"),QStringLiteral("请选择脚本分类"));
        return;
    }
    if(m_scriptDir.trimmed().isEmpty()){
        QMessageBox::information(NULL,QStringLiteral("增加分类"),QStringLiteral("请先设置脚本目录"));
        return;
    }
    QString scriptname = QInputDialog::getText(this,QStringLiteral("添加新脚本"),QStringLiteral("请输入脚本文件名称"));
    if(scriptname.trimmed().isEmpty()){
        return;
    }
    if(m_scriptList.contains(scriptname)){
        QString scriptname = QInputDialog::getText(this,QStringLiteral("添加新脚本"),QStringLiteral("文件名已存在"));
        return;
    }
    m_scriptList << scriptname;
    ui->listnames->addItem(m_scriptList.last()+"*");
    ui->listnames->setCurrentRow(ui->listnames->count()-1);
    ui->plainTextEdit->setPlainText("");
    m_lastScript = m_scriptList.last();
    m_tag = true;
}

void ScriptManager::on_btnDir_clicked()
{
    QString dir = QFileDialog::getExistingDirectory(this,QStringLiteral("选择目录"),"./",QFileDialog::ShowDirsOnly);
    if(dir.trimmed().isEmpty()){
        return;
    }
    QSettings *reg = new QSettings("HKEY_CURRENT_USER\\Software\\ScriptWizard", QSettings::NativeFormat);
    reg->setValue("ScriptPath",dir);
    m_scriptDir = dir;
    ui->lineEdit->setText(m_scriptDir);
}

void ScriptManager::on_btnRun_clicked()
{
    if(m_lastScript.endsWith(".bat")){
        QTemporaryDir dir;
        if(dir.isValid()){
            QString filepath = dir.path()+"/ScriptRun.bat";
            QFile file(filepath);
            if (!file.open(QIODevice::WriteOnly)) {
                QMessageBox::information(NULL,QStringLiteral("脚本运行"),QStringLiteral("无法运行脚本:")+filepath);
                return;
            }
            file.write(ui->plainTextEdit->toPlainText().replace("\n","\r\n").toLocal8Bit());
            file.close();
            if(ui->checkBox->isChecked()){
                system(("cmd " + filepath.toStdString()).c_str());
                return;
            }
            system(("cmd /k " + filepath.toStdString()).c_str());
        }
    }else if(m_lastScript.endsWith(".py")){
        QTemporaryDir dir;
        if(dir.isValid()){
            QString filepath = dir.path()+"/ScriptRun.py";
            QFile file(filepath);
            if (!file.open(QIODevice::WriteOnly)) {
                QMessageBox::information(NULL,QStringLiteral("脚本运行"),QStringLiteral("无法运行脚本:")+filepath);
                return;
            }
            file.write(ui->plainTextEdit->toPlainText().replace("\n","\r\n").toUtf8());
            file.close();
            if(ui->checkBox->isChecked()){
                system(("cmd python " + filepath.toStdString()).c_str());
                return;
            }
            system(("cmd /k python " + filepath.toStdString()).c_str());
        }
    }else if(m_lastScript.endsWith(".ps1")){
        QTemporaryDir dir;
        if(dir.isValid()){
            QString filepath = dir.path()+"/ScriptRun.ps1";
            QFile file(filepath);
            if (!file.open(QIODevice::WriteOnly)) {
                QMessageBox::information(NULL,QStringLiteral("脚本运行"),QStringLiteral("无法运行脚本:")+filepath);
                return;
            }
            file.write(ui->plainTextEdit->toPlainText().replace("\n","\r\n").toLocal8Bit());
            file.close();
            if(ui->checkBox->isChecked()){
                system(("powershell -exec bypass -C " + filepath.toStdString()).c_str());
                return;
            }
            system(("powershell -NoExit -exec bypass -C " + filepath.toStdString()).c_str());
        }
    }
}

void ScriptManager::on_listclasses_itemDoubleClicked(QListWidgetItem *item)
{
    if(ui->listnames->currentItem()){
        CheckSave(ui->listnames->currentItem()->text());
        ui->listnames->currentItem()->setText(ui->listnames->currentItem()->text().remove("*"));
    }
    ScanScripts(item->text());
}

void ScriptManager::on_listnames_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
{
    if(previous == NULL){
        return;
    }
    if(previous->text().endsWith("*")){
        CheckSave(previous->text());
        LoadScript(current->text());
        previous->setText(previous->text().remove("*"));
    }
}

void ScriptManager::on_plainTextEdit_textChanged()
{
    if(ui->listnames->count()==0){
        return;
    }
    if(m_tag&&!ui->listnames->currentItem()->text().endsWith("*")){
        ui->listnames->currentItem()->setText(ui->listnames->currentItem()->text()+"*");
    }
}

void ScriptManager::on_listnames_itemClicked(QListWidgetItem *item)
{
    LoadScript(item->text());
    m_lastScript = item->text();
}

void ScriptManager::on_btnDelelteScript_clicked()
{
    if(!ui->listnames->currentItem()){
        return;
    }
    QMessageBox::StandardButton defaultBtn=QMessageBox::NoButton; //缺省按钮
    QMessageBox::StandardButton result;//返回选择的按钮
    result=QMessageBox::question(this, QStringLiteral("删除脚本"), QStringLiteral("是否要删除脚本\"")+ui->listnames->currentItem()->text()+"\"?",
                                 QMessageBox::Yes|QMessageBox::No,
                                 defaultBtn);
    if (result==QMessageBox::Yes){
        int row = ui->listnames->row(ui->listnames->currentItem());
        QFile file(m_scriptDir+"/"+ui->listclasses->currentItem()->text()+"/"+ui->listnames->currentItem()->text());
        file.remove();
        m_scriptList.removeAt(row);
        QListWidgetItem* widgetitem = ui->listnames->currentItem();
        ui->listnames->removeItemWidget(widgetitem);
        delete widgetitem;
        if(row == 0){
            ui->plainTextEdit->setPlainText("");
        }else if(--row < 0){
            row = 0;
            ui->listnames->setCurrentRow(row);
            LoadScript(ui->listnames->currentItem()->text());
        }
    }
}

bool deleteDir(const QString &dirName)
{
    QDir directory(dirName);
    if (!directory.exists()){
        return true;
    }

    QString srcPath = QDir::toNativeSeparators(dirName);
    if (!srcPath.endsWith(QDir::separator()))
        srcPath += QDir::separator();

    QStringList fileNames = directory.entryList(QDir::AllEntries | QDir::NoDotAndDotDot | QDir::Hidden);
    bool error = false;
    for (QStringList::size_type i=0; i != fileNames.size(); ++i)
    {
        QString filePath = srcPath + fileNames.at(i);
        QFileInfo fileInfo(filePath);
        if (fileInfo.isFile() || fileInfo.isSymLink())
        {
            QFile::setPermissions(filePath, QFile::WriteOwner);
            if (!QFile::remove(filePath))
            {
                qDebug() << "remove file" << filePath << " faild!";
                error = true;
            }
        }
        else if (fileInfo.isDir())
        {
            if (!deleteDir(filePath))
            {
                error = true;
            }
        }
    }

    if (!directory.rmdir(QDir::toNativeSeparators(directory.path())))
    {
        qDebug() << "remove dir" << directory.path() << " faild!";
        error = true;
    }
    return !error;
}

void ScriptManager::on_btnDelelteClass_clicked()
{
    if(!ui->listclasses->currentItem()){
        return;
    }
    QMessageBox::StandardButton defaultBtn=QMessageBox::NoButton; //缺省按钮
    QMessageBox::StandardButton result;//返回选择的按钮
    result=QMessageBox::question(this, QStringLiteral("删除分类"), QStringLiteral("是否要删除分类\"")+ui->listclasses->currentItem()->text()+"\"?",
                                 QMessageBox::Yes|QMessageBox::No,
                                 defaultBtn);
    if (result==QMessageBox::Yes){
        int row = ui->listclasses->row(ui->listclasses->currentItem());
        deleteDir(m_scriptDir+"/"+ui->listclasses->currentItem()->text());
        m_scriptList.removeAt(row);
        QListWidgetItem* widgetitem = ui->listclasses->currentItem();
        ui->listclasses->removeItemWidget(widgetitem);
        delete widgetitem;
        if(row == 0){
            ui->plainTextEdit->setPlainText("");
        }else if(--row < 0){
            row = 0;
            ui->listclasses->setCurrentRow(row);
            ScanScripts(ui->listclasses->currentItem()->text());
        }
    }
}

void ScriptManager::on_btnSaveScript_clicked()
{
    if(ui->listnames->currentItem()){
        QString scriptName = ui->listnames->currentItem()->text().trimmed();
        if(scriptName.endsWith("*")){
            QFile file(m_scriptDir+"/"+m_lastClass+"/"+scriptName.remove("*"));
            if(file.open(QIODevice::WriteOnly|QIODevice::Truncate)){
                file.write(ui->plainTextEdit->toPlainText().replace("\n","\r\n").toLocal8Bit());
            }
            file.close();
        }
        ui->listnames->currentItem()->setText(scriptName);
    }
}
